package cn.yj.netty.message.chain;

import cn.yj.netty.message.eventshander.MessageHandlerFactory;
import cn.yj.netty.message.heart.IHeartBeatMonitor;
import cn.yj.netty.message.listener.NettyMessageListener;
import cn.yj.netty.support.test.MessageProtocol;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 数据前期处理通过，将消息分发到对应的业务函数中
 *
 * @author 永健
 * @since 2022-02-16 14:14
 */
@Component
public class DispatchHandler extends AbstractMessageChain<MessageProtocol> {
    private static final Logger log = LoggerFactory.getLogger(DispatchHandler.class);

    @Resource
    private List<NettyMessageListener> dispatchListener;

    @Resource
    private IHeartBeatMonitor heartBeatMonitor;


    private static ExecutorService EXECUTORS = Executors.newFixedThreadPool(5);

    @Override
    void doHandler(ChannelHandlerContext channelHandlerContext, MessageProtocol msg) {
        log.info("消息分发到具体的 handler中,host={},commandCode={}", getHost(), msg.getHeader().getCommandCode());


        String commandCode = msg.getHeader().getCommandCode();
        try {
            // ((MessageHandler) SpringBean.getBean(commandCode)).receiveMsg(result, channelHandlerContext);
            MessageHandlerFactory.getFactory().getHandler(msg).receiveMsg(msg, channelHandlerContext);
        } catch (Exception e) {
            log.error("没有对应的消息处理器，commandCode = {}", commandCode);
        }


        EXECUTORS.execute(() -> {

            // 通知所有的消息监听器
            dispatchListener.forEach(listener -> {
                try {
                    listener.listener(msg, channelHandlerContext);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });

            // 重新计算心跳时间
            try {
                heartBeatMonitor.doReadTriggered(channelHandlerContext);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });


        if (!ObjectUtils.isEmpty(getNextChain())) {
            getNextChain().handler(channelHandlerContext, msg);
        }
    }
}
